﻿package com._public._ui
{
	import flash.display.MovieClip;
	import flash.display.Shape;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	import flash.text.TextField;
	import flash.ui.Mouse;
	
	/**
	 * ...
	 * @author 咸鱼 qq:181404930(www.shch8.com)
	 * 例子
	 * import ScComboBox;
		var cb:ScComboBox = new ScComboBox(100,22);
		cb.x = cb.y = 200;
		addChild(cb);
		cb.draw()//配置完成以后需要执行draw()才能生效，并且可以设置样式
		cb.addItem({label:"测试测试1"});
		cb.addItem({label:"测试测试2"});
		cb.addItem({label:"测试测试3"});
		cb.addItem({label:"测试测4"});
		cb.addItem({label:"测试测5"});
		cb.addItem({label:"测试测6"});
		cb.addItem({label:"测试测7"});
		cb.useOnlyList = true;//是否独立使用list
		
		* @param 皮肤与样式 注：不支持动态重绘
		* 如
		cb.style.boxLine = 0xcccccc; //边框颜色
		cb.style.boxFill = 0xf0f0f0;//填充色
		cb.style.downBut = 0xcccccc;//下拉按钮颜色
		cb.style.iconFill = 0x333333;//下拉ICON三角形颜色
		cb.style.textColor = 0x333333;//文本颜色
		cb.style.barBg = 0xeeeeee;//滚动条背景颜色
		cb.style.barColor = 0xaaaaaa;//滚动条颜色
		cb.style.itemLine = 0xaaaaaa;//选择条边框颜色
		cb.style.itemFill = 0xffffff;//选择条填充色
		cb.style.itemSel = 0xcc0000;//选取颜色
		
		cb.style.boxFace//这是Sprite对象，用于下拉框可视皮肤的设置
		cb.style.barFace//这是Sprite对象，用于滚动条的可视皮肤设置
		cb.style.itemHei //选取条的高度
		
		* @param 设置参数
		//获取当前选中项的数据对象
		public function get selectedItem():Object
		//文本获取
		public function get textField():TextField
		//是否使用List模式
		public function set useOnlyList(bool:Boolean):void
		//通过键值删除项
		public function removeItem(index:int):void
		//添加项
		public function addItem(obj:Object):void
		//获取当前选中项的键值
		public function get selectedIndex():int
		//通过键值选中项...
		public function set selectedIndex(index:int):void
		//使用批量缓存数据，只有下拉显示时才添加到列表
		public function set dataCatch(value:Array):void
		//滚动刻度
		public function set delay(value:uint):void
	 */
	[Event(name = "change", type = "flash.events.Event")]
	public class ScComboBox extends Sprite
	{
		private var _selectedBox:Sprite;
		private var _selectedTxt:TextField;
		private var _listBox:Sprite;
		private var _width:Number = 0;
		private var _height:Number = 0;
		private var _items:Array;
		private var _datas:Array;
		private var _selectedItem:ListItem;
		private var _listMask:Shape;
		private var _screenBar:Sprite;
		private var _bar:Sprite;
		private var _useOnlyList:Boolean;
		private var _listHei:Number//列表高度
		private var _list:Sprite;
		private var _barFace:MovieClip
		private var _listBordLine:Sprite
		private var _dataCatch:Array
		private var _delay:uint = 5
		private var _txtName:String
		public var style:ParamSet=new ParamSet
		public function ScComboBox(wid:Number = 100, hei:Number = 22,listHei:Number=150,itemHei:Number = 20,txtName:String="txt")
		{
			_txtName = txtName;
			_datas = [];
			_items = [];
			_width = wid;
			_height = hei;
			_listHei=listHei;
			style.itemHei = itemHei;
			this.addEventListener(Event.ADDED_TO_STAGE, addListen);
		}
		public function set listHei(value:Number):void { _listHei = value };
		public function get listHei():Number{return _listHei};
		//文本获取
		public function get textField():TextField{return _selectedTxt}
		//是否使用List模式
		public function set useOnlyList(bool:Boolean):void
		{
			_useOnlyList = bool;
			if (bool)
			{
				stage&&stage.removeEventListener(MouseEvent.CLICK, selectedBoxClick);
				_selectedBox.stage && removeChild(_selectedBox);
				!_list.stage && addChild(_list);
			}else
			{
				stage&&stage.addEventListener(MouseEvent.CLICK, selectedBoxClick);
				!_selectedBox.stage && addChild(_selectedBox);
				_list.stage && _list.parent.removeChild(_list);
			}
		}
		
		//使用批量缓存数据，只有下拉显示时才添加到列表
		public function set dataCatch(value:Array):void
		{
			_dataCatch=value
		}
		//滚动刻度
		public function set delay(value:uint):void
		{
			_delay=value
		}
		override public function get width():Number {return _width; }
		
		override public function set width(value:Number):void
		{
			_width = value;
		}
		override public function get height():Number { return _height; }
		
		override public function set height(value:Number):void
		{
			_height = value;
		}
		public function draw():void
		{
			if(_list==null)
			_list = new Sprite;
			var butWid:uint = 20
			if(_selectedBox==null){
			_selectedBox = new Sprite;
			if (style.boxFace != null) {
				_selectedBox = style.boxFace as Sprite
				_selectedTxt = _selectedBox.getChildByName(_txtName) as TextField
				if(_selectedTxt==null)throw("皮肤里面没有找到名为‘txt’的文本对象")
			}else{
				_selectedBox.graphics.lineStyle(1, style.boxLine,1,true);
				_selectedBox.graphics.beginFill(style.boxFill);
				_selectedBox.graphics.drawRoundRect(0, 0, _width, _height, 3, 3);
				_selectedBox.graphics.endFill();
				
				
				_selectedBox.graphics.beginFill(style.downBut);
				_selectedBox.graphics.drawRoundRect(_width - butWid, 0, butWid, _height, 3, 3);
				_selectedBox.graphics.endFill();
				
				_selectedBox.graphics.lineStyle(1, 0xf9f9f9, 1, true);
				_selectedBox.graphics.drawRoundRect(1, 1, _width-2, _height-2, 3, 3);
				_selectedBox.graphics.endFill();
				//_selectedTxt.border=true
				var icon:Shape = new Shape
				icon.graphics.beginFill(style.iconFill);
				icon.graphics.lineStyle(1, style.iconFill, 1);
				icon.graphics.moveTo(1, 1);
				icon.graphics.lineTo(7, 1);
				icon.graphics.lineTo(4, 5);
				icon.graphics.lineTo(1, 1);
				icon.graphics.endFill();
				icon.x = _width - butWid+(butWid-icon.width)/2
				icon.y=(_height-icon.height)/2
				_selectedBox.addChild(icon)
				_selectedTxt = new TextField;
				//_selectedTxt.mouseEnabled = false;
				_selectedTxt.tabEnabled = false
				_selectedTxt.selectable = true;
				_selectedTxt.width = _width - butWid-5
				_selectedTxt.height=20
				_selectedTxt.setTextFormat(style.barText);
				_selectedTxt.x = 5
				_selectedTxt.y = (_height - 20) / 2
				_selectedBox.addChild(_selectedTxt);
			}
			addChild(_selectedBox);
			_selectedBox.addEventListener(MouseEvent.MOUSE_OVER, barOver);
			}
			_listBox = new Sprite;
			_listMask = new Shape;
			_listMask.graphics.beginFill(0);
			_listMask.graphics.drawRect(0, 0, _width, _listHei);
			_listMask.graphics.endFill();
			_listBox.mask = _listMask;
			_list.addChild(_listMask);
			_list.addChild(_listBox);
			if (_listBordLine == null)_listBordLine = new Sprite; _list.addChild(_listBordLine);
			if (_screenBar != null) return;
			_screenBar = new Sprite;
			_screenBar.graphics.beginFill(style.barBg);
			_screenBar.graphics.drawRect(0, 0, 12, _listMask.height);
			_screenBar.graphics.endFill();
			_screenBar.addEventListener(MouseEvent.CLICK,skipHandler);
			if(style.barFace==null){
			_bar = new Sprite;
			_bar.graphics.beginFill(style.barColor)
			_bar.graphics.drawRect(0, 0, 12, 40);
			_bar.graphics.endFill();
			}else {
				_bar = style.barFace;
				}
			_screenBar.x = _listMask.width - _screenBar.width;
			_screenBar.addChild(_bar);
			
			_bar.addEventListener(MouseEvent.MOUSE_DOWN, barDown);
			_bar.addEventListener(MouseEvent.MOUSE_OVER, barOver);
			_listBox.addEventListener(MouseEvent.MOUSE_WHEEL, wheel);
		}
	

		private function skipHandler(e:MouseEvent):void
		{
			trace(e.target.mouseY > _bar.y+_bar.height )
			var dis:int = 5;
			if(Math.abs(e.target.mouseY - _bar.y) < 15)
			{
				return;
			}
			if(e.target.mouseY > _bar.y +_bar.height)
			{
				_bar.y += (e.target.mouseY - _bar.y)/dis;
				
			}
			if(e.target.mouseY < _bar.y)
			{
				_bar.y -= (_bar.y - e.target.mouseY)/dis;
			}

			_listBox.y = -_bar.y / (_listMask.height - _bar.height) * (_listBox.height - _listMask.height);
		
		}
		private function barOver(evt:MouseEvent):void
		{
			evt.target.addEventListener(MouseEvent.MOUSE_OUT, barOut);
			evt.target.alpha=0.8
		}
		private function barOut(evt:MouseEvent):void
		{
			evt.target.removeEventListener(MouseEvent.MOUSE_OUT, barOut);
			evt.target.alpha=1
		}
		private function barDown(evt:MouseEvent):void
		{
			var rect:Rectangle = new Rectangle(0, 0, 0, _screenBar.height - _bar.height);
			_bar.startDrag(false, rect);
			_bar.stage.addEventListener(MouseEvent.MOUSE_UP, barUp);
			_bar.addEventListener(Event.ENTER_FRAME, onEnter);
		}
		private function onEnter(evt:Event):void
		{
			_listBox.y = -_bar.y / (_listMask.height - _bar.height) * (_listBox.height - _listMask.height);
		}
		private function barUp(evt:MouseEvent):void
		{
			_bar.stopDrag();
			_bar.stage.removeEventListener(MouseEvent.MOUSE_UP, barUp);
			_bar.removeEventListener(Event.ENTER_FRAME, onEnter);
		}
		//通过键值删除项
		public function removeAll():void
		{
			
			_items = new Array
			_datas = new Array
			if(_list.stage)_list.parent.removeChild(_list)
			_list = null
			draw()
		}
		//通过键值删除项
		public function removeItem(index:int):void
		{
			if (index<0||index>_items.length)
			{
				throw Error("设置的Index超出范围!");
			}else
			{
				var key:int = _items.indexOf(_selectedItem);
				var bo:Boolean = false;
				if (key == index)
				{
					bo = true;
				}
				_items.splice(index, 1);
				_datas.splice(index, 1);
				for (var i:int = 0, len:int = _items.length; i < len; i += 1 )
				{
					var item:* = _items[i];
					item.y = item.height * i;
					if (bo && i == 0)
					{
						_selectedItem = item;
						item.select = true;
						_selectedTxt.text = item.label;
			
					}
				}
			}
		}
		//添加项
		public function addMore(ary:Array):void
		{
			removeAll();
			for (var i:uint; i < ary.length; i++ ) {
					addItem(ary[i])
			}
			
		}
		//添加项
		public function addItem(obj:Object):void
		{
			var addObj:String
			try {
				addObj=String(obj.label)
			} catch (e:Error) {
				addObj=String(obj)
			}
			var item:ListItem = new ListItem(addObj,style,_width);
			
			var key:int = _items.length;
			item.y = item.height * key;
			item.x = .5;
			_items[key] = item;
			_datas[key] = obj;
			if (key == 0)
			{
				_selectedItem = item;
				item.select = true;
				_selectedTxt.text = item.label;
			}
			
			item.addEventListener(MouseEvent.CLICK, itemClick);
			_listBox.addChild(item);
			var barHei:uint = uint(_listMask.height * _listMask.height / _listBox.height)
			if(barHei<15)barHei=15
			_bar.height = barHei
			_listBordLine.graphics.clear()
			var setHei:Number = item.height * (key + 1)
			if (setHei > _listHei) setHei = _listHei;
			_listBordLine.graphics.lineStyle(1, style.boxLine)
			_listBordLine.graphics.drawRect(0, 0, _width,setHei)
			
			if (_listBox.height > _listMask.height)
			{
				!_screenBar.stage && _list.addChild(_screenBar);
			}else
			{
				_screenBar.stage && _screenBar.parent.removeChild(_screenBar);
			}
		}
		
		public function get selectedID():Object
		{
			var key:int = _items.indexOf(_selectedItem);
			return _datas[key].id;
		}
		public function set selectedID(value:Object):void
		{
			for (var i:uint; i < _datas.length; i++ ) {
				if (_datas[i].id == value.id) {
					selectedIndex = i;
					return
				}
			}
		}
		//获取当前选中项的数据对象
		public function get selectedItem():Object
		{
			var key:int = _items.indexOf(_selectedItem);
			return _datas[key];
		}
		public function set selectedItem(value:Object):void
		{
			for (var i:uint; i < _datas.length; i++ ) {
				if (_datas[i].label == value.label) {
					selectedIndex = i;
					return
				}
			}
		}
		//获取当前选中项的键值
		public function get selectedIndex():int
		{
			var key:int = _items.indexOf(_selectedItem);
			return key;
		}
		//通过键值选中项...
		public function set selectedIndex(index:int):void
		{
			if(index==selectedIndex)return
			if (index<0||index>_items.length)
			{
				throw Error("设置的Index超出范围!");
			}else
			{
				var key:int = _items.indexOf(_selectedItem);
				var item:ListItem = _items[index];
				if(_selectedItem)(_selectedItem.select = false);
				item.select = true;
				_selectedItem = item;
				_selectedTxt.text = _selectedItem.label;
	
				item = null;
			}
		}
		private function itemClick(evt:MouseEvent):void
		{
			if (evt.currentTarget != _selectedItem)
			{
				_selectedItem && (_selectedItem.select = false);
				evt.currentTarget.select = true;
				_selectedItem = evt.currentTarget as ListItem;
				_selectedTxt.text = _selectedItem.label;
				dispatchEvent(new Event(Event.CHANGE))
			}
		}
		private function addListen(e:Event):void
		{
			this.stage.addEventListener(MouseEvent.CLICK, selectedBoxClick);
			this.addEventListener(Event.REMOVED_FROM_STAGE,removeEvent);
		}
		private function removeEvent(e:Event):void
		{
			this.stage.removeEventListener(MouseEvent.CLICK, selectedBoxClick);
			this.removeEventListener(Event.REMOVED_FROM_STAGE,removeEvent);
		}
		private function wheel(e:MouseEvent):void
		{
			var maxScroll:Number = _screenBar.height - _bar.height;
			_bar.y += e.delta<0?_delay:-_delay
			if (_bar.y > maxScroll)_bar.y = maxScroll;
			if (_bar.y <0)_bar.y = 0;
			onEnter(null)
		}
		private function selectedBoxClick(evt:MouseEvent):void
		{
			if (isOr())
			{
				if(!_useOnlyList)stage.removeChild(_list);
			}else if (!_listBox.stage && (evt.target == _selectedBox|| evt.target.parent == _selectedBox) && evt.target!=textField)
			{
				if (_dataCatch != null) {
					for (var i:uint; i < _dataCatch.length; i++ ) {
						addItem(_dataCatch[i])
						}
					_dataCatch = null;
					}
				var pos:Point = localToGlobal(new Point(0,0));
				_list.x = pos.x
				var setY:Number = pos.y +_selectedBox.height;
				if(stage.stageHeight<setY+listHei+50){
					setY= pos.y -listHei;
				}
				_list.y = setY;
				stage.addChild(_list);
				
			}
			function isOr():Boolean
			{
				var re:Boolean = _listBox.stage && evt.target != _screenBar && evt.target != _bar && evt.target.parent != _bar;
				return re
			}
		}
	}
	
}
import flash.display.Sprite;
import flash.text.TextFormat;
//设置对象
class ParamSet
{
		public var boxLine:uint = 0xcccccc; //边框颜色
		public var boxFill:uint = 0xf0f0f0;//填充色
		public var downBut:uint = 0xcccccc;//下拉按钮颜色
		public var iconFill:uint = 0x333333;//下拉ICON三角形颜色
		public var itemText:TextFormat = new TextFormat//选取项目文字样式
		public var barText:TextFormat = new TextFormat//文本样式
		public var barBg:uint = 0xeeeeee;//滚动条背景颜色
		public var barColor:uint = 0xaaaaaa;//滚动条颜色
		public var itemLine:uint = 0xaaaaaa;//选择条边框颜色
		public var itemFill:uint = 0xffffff;//选择条填充色
		public var itemSel:uint = 0x2F82FF;//选取颜色
		/*这是Sprite对象，用于下拉框可视皮肤的设置*/
		public var boxFace:Sprite
		/*这是Sprite对象，用于滚动条的可视皮肤设置*/
		public var barFace:Sprite
		/*选取条的高度*/
		public var itemHei:uint=20
	
}
import flash.events.MouseEvent;
import flash.text.TextField;
import flash.display.Sprite;
import flash.display.Shape;
class ListItem extends Sprite
{
	private var _txt:TextField;
	private var _width:Number = 0;
	public var _height:Number = 0;
	private var _lineColor:uint;
	private var _bgColor:uint;
	private var _mask:Shape;
	private var _box:Shape;
	private var _selected:Boolean = false;
	private var _selectedItem:Object;
	private var _str:String
	public function ListItem(str:String,style:ParamSet,_wid:Number=99)
	{
		_width = _wid
		_height = style.itemHei;
		_str = str;
		_lineColor = style.itemLine;
		_bgColor = style.itemFill;
		_txt = new TextField;
		_txt.defaultTextFormat=style.itemText;
		_txt.mouseEnabled = false;
		_txt.autoSize = "left";
		_txt.text = str;
		_txt.x=3;
		_txt.y = _height/2 - _txt.height/2
		addChild(_txt);
		_mask = createShape(0, _width, _height);
		_box = createShape(style.itemSel, _width, _height);
		_box.visible = false;
		addChild(_box)
		_txt.mask = _mask;
		addChild(_mask);
		refresh();
		this.addEventListener(MouseEvent.MOUSE_OVER, onOver);
	}
	public function get label():String
	{
		return _str;
	}
	private function createShape(color:uint,wid:Number,hei:Number):Shape
	{
		var s:Shape = new Shape
		s.graphics.beginFill(color);
		s.graphics.drawRect(0, 0, wid, hei);
		s.graphics.endFill();
		return s;
	}
	public function set select(value:Boolean):void
	{
		_selected = value;
		if (value)
		{
			_box.alpha = .5;
			_box.visible = true;
		}else
		{
			_box.alpha = .1;
			_box.visible = false;
		}
		onOut(null)
	}
	private function onOver(evt:MouseEvent):void
	{
		if (!_selected)
		{
			_box.alpha = .1;
			this.addEventListener(MouseEvent.MOUSE_OUT, onOut);
			_box.visible = true;
		}
	}
	private function onOut(evt:MouseEvent):void
	{
		this.removeEventListener(MouseEvent.MOUSE_OUT, onOut);
		if (!_selected)
		{
			_box.visible = false;
		}
	}
	private function refresh():void
	{
		this.graphics.lineStyle(1, _lineColor);
		this.graphics.beginFill(_bgColor);
		this.graphics.drawRect(0, 0, _width, _height);
		this.graphics.endFill();
	}
	override public function set width(value:Number):void
	{
		_mask.width = _width = width;
		refresh();
	}
	override public function set height(value:Number):void
	{
		_mask.height = _height = height;
		refresh();
	}
	override public function get width():Number
	{
		return _width;
	}
	override public function get height():Number
	{
		return _height;
	}
}
